const {appid, secret} = require('./wx-secret.json')
const Koa = require('koa')
const app = new Koa()
const axios = require('axios')
const fs = require('fs')
const path = require('path')
const sha1 = require('sha1')

function getCachedToken() {
  try {
    let res = require('./wx-token.json')
    if (Date.now() >= res.expires_at) {
      throw 123
    }

    return res
  } catch (e) {
    return null
  }
}

async function refreshToken() {
  let res = await axios.get('https://api.weixin.qq.com/cgi-bin/token', {
    params: {
      grant_type: 'client_credential',
      appid,
      secret,
    }
  })
  return res.data
}

async function getToken() {
  let res = getCachedToken()
  if (!res) {
    let {expires_in, access_token} = await refreshToken()
    fs.writeFileSync(path.join(__dirname, './wx-token.json'), JSON.stringify({
      access_token,
      expires_at: Date.now() + (expires_in - 30) * 1000
    }))
    return access_token
  } else {
    return res.access_token
  }
}

async function getJsTicket(access_token) {
  try {
    let res = require('./wx-js-ticket.json')
    if (Date.now() >= res.expires_at) {
      throw 123
    }
    return res.ticket
  } catch (e) {
    let res = await axios.get('https://api.weixin.qq.com/cgi-bin/ticket/getticket', {
      params: {
        access_token,
        type: 'jsapi'
      }
    })

    let {ticket, expires_in} = res.data
    fs.writeFileSync(path.join(__dirname, './wx-js-ticket.json'), JSON.stringify({
      ticket,
      expires_at: Date.now() + (expires_in - 30) * 1000
    }))

    return ticket
  }
}


function sign({url, ticket}) {
  let timestamp = Math.floor(Date.now() / 1000)
  let nonceStr = 'Wm3WZYTPz0wzccnW' + Math.floor(Math.random() * 100)
  let signature = sha1(`jsapi_ticket=${ticket}&noncestr=${nonceStr}&timestamp=${timestamp}&url=${url}`)
  return {
    appId: appid, // 必填，公众号的唯一标识
    timestamp, // 必填，生成签名的时间戳
    nonceStr, // 必填，生成签名的随机串
    signature,// 必填，签名
  }

}


app.use(async (ctx, next) => {
  let {action} = ctx.query

  if (action === 'jsticket') {
    let token = await getToken()
    let ticket = await getJsTicket(token)
    ctx.body = sign({url: ctx.header['referer'], ticket})
  } else {
    ctx.throw(400)
  }
})

app.listen(64001, '127.0.0.1')